/**
 * @file LyricTool.cpp
 * @brief 歌词解析和加载工具实现
 * @details 实现了歌词解析、排序和从文件加载歌词的功能
 */

#include <iostream>
#include <cctype>
#include <cstdlib>
#include <glib.h>
#include "utils.h"
#include "LyricTool.h"
#include "lyric_log.h"

/**
 * @brief 比较两个歌词行对象的时间戳
 * @param a 第一个LyricLine对象指针
 * @param b 第二个LyricLine对象指针
 * @return 比较结果，-1表示a小于b，0表示相等，1表示a大于b
 */
gint int_compare(gconstpointer a, gconstpointer b) {
    LyricLine* line1 = (LyricLine*)a;
    LyricLine* line2 = (LyricLine*)b;
    gdouble ret = line1->timestamp - line2->timestamp;
    if (ret < -0.000001f)
        return -1;
    else if (ret > 0.000001f)
        return 1;
    return 0;
}

// 使用 GLib 正则表达式解析歌词行，提取时间戳和歌词内容
static gboolean parse_lyric_line(const gchar* line, gdouble* timestamp, gchar** lyric_text) {
    if (!line || !timestamp || !lyric_text) {
        return FALSE;
    }
    
    // 使用 GLib 正则表达式匹配时间戳格式
    static GRegex* regex = NULL;
    if (!regex) {
        // 匹配 [mm:ss.xx] 或 [mm:ss.xxx] 格式
        regex = g_regex_new("\\[([0-9]{2}):([0-9]{2})\\.([0-9]{2,3})\\]", G_REGEX_OPTIMIZE, (GRegexMatchFlags)0, NULL);
        if (!regex) {
            lyric_log_error("parse_lyric_line: failed to compile regex");
            return FALSE;
        }
    }
    
    GMatchInfo* match_info = NULL;
    if (g_regex_match(regex, line, (GRegexMatchFlags)0, &match_info)) {
        gchar* minutes_str = g_match_info_fetch(match_info, 1);
        gchar* seconds_str = g_match_info_fetch(match_info, 2);
        gchar* milliseconds_str = g_match_info_fetch(match_info, 3);
        
        gint minutes = g_ascii_strtoll(minutes_str, NULL, 10);
        gint seconds = g_ascii_strtoll(seconds_str, NULL, 10);
        gint milliseconds = g_ascii_strtoll(milliseconds_str, NULL, 10);
        
        // 计算时间戳（秒）
        gint divisor = (strlen(milliseconds_str) == 2) ? 100 : 1000;
        *timestamp = minutes * 60.0 + seconds + (gdouble)milliseconds / divisor;
        
        // 提取歌词文本（时间戳后面的内容）
        // 获取完整匹配的字符串以找到其在原始行中的位置
        gchar* full_match = g_match_info_fetch(match_info, 0);
        if (full_match) {
            // 使用 GLib 的字符串查找函数，-1 表示搜索整个字符串
            gchar* match_pos = g_strstr_len(line, -1, full_match);
            if (match_pos) {
                gsize full_match_len = strlen(full_match);
                gsize line_len = strlen(line);
                gint start_pos = (match_pos - line) + full_match_len;
                if (start_pos < (gint)line_len) {
                    *lyric_text = trim(line + start_pos);
                } else {
                    *lyric_text = g_strdup("");
                }
            } else {
                *lyric_text = g_strdup("");
            }
            g_free(full_match);
        } else {
            *lyric_text = g_strdup("");
        }
        
        g_free(minutes_str);
        g_free(seconds_str);
        g_free(milliseconds_str);
        g_match_info_free(match_info);
        
        return TRUE;
    }
    
    g_match_info_free(match_info);
    return FALSE;
}

/**
 * @brief 解析歌词文本，提取时间戳和歌词内容
 * @param lyric_txt 歌词文本字符串
 * @return 包含所有歌词行的GList链表
 */
GList* parse_lyrics(gchar* lyric_txt)
{
    GList* lyrics = NULL;
    
    // 首先检查 NULL 指针（必须在 strlen 之前）
    if (!lyric_txt) {
        lyric_log_warning("parse_lyrics: input is NULL");
        return lyrics;
    }
    
    // 检查空字符串
    gsize txt_len = strlen(lyric_txt);
    if (txt_len == 0) {
        lyric_log_warning("parse_lyrics: input is empty");
        return lyrics;
    }
    
    lyric_log_debug("parse_lyrics: starting, input length: %zu", txt_len);

    // 处理特殊情况：如果最后一个字符是']'，添加空格
    // 注意：此时 lyric_txt 已经确定不为 NULL 且长度 > 0
    if (txt_len > 0 && lyric_txt[txt_len - 1] == ']') {
        gchar* temp = g_strconcat(lyric_txt, " ", NULL);
        g_free(lyric_txt);
        lyric_txt = temp;
        txt_len = strlen(lyric_txt);  // 更新长度
    }
    
    // 重新检查长度（可能在添加空格后）
    if (strlen(lyric_txt) <= 3) {
        lyric_log_warning("parse_lyrics: input too short (after processing)");
        return lyrics;
    }

    // 按行分割歌词文本
    lyric_log_debug("parse_lyrics: splitting text into lines");
    gchar** lines = g_strsplit(lyric_txt, "\n", -1);
    gint line_count = g_strv_length(lines);
    lyric_log_debug("parse_lyrics: split into %d lines", line_count);
    
    gint processed_count = 0;
    gint matched_count = 0;
    
    lyric_log_debug("parse_lyrics: starting processing loop (using GLib regex)");
    
    // 遍历每一行歌词，使用 GLib 正则表达式
    for (gint i = 0; lines[i] != NULL; i++) {
        processed_count++;
        
        // 每处理 20 行输出一次进度（减少日志量）
        if (processed_count % 20 == 0) {
            lyric_log_debug("parse_lyrics: processed %d/%d lines, matched %d", processed_count, line_count, matched_count);
        }
        
        gdouble timestamp = 0.0;
        gchar* lyric_text = NULL;
        
        // 使用 GLib 正则表达式解析函数
        if (parse_lyric_line(lines[i], &timestamp, &lyric_text)) {
            // 跳过太短的歌词行
            if (strlen(lyric_text) < 2) {
                g_free(lyric_text);
                continue;
            }
            
            // 创建新的歌词行对象
            LyricLine* lyric_line = g_slice_new0(LyricLine);
            lyric_line->timestamp = timestamp;
            lyric_line->text = lyric_text;
            lyrics = g_list_append(lyrics, lyric_line);
            matched_count++;
        }
    }
    
    lyric_log_debug("parse_lyrics: processed all lines, matched %d lines", matched_count);
    
    // 按时间戳排序歌词
    lyric_log_debug("parse_lyrics: sorting lyrics");
    lyrics = g_list_sort(lyrics, int_compare);
    lyric_log_debug("parse_lyrics: sorting completed, final count: %d", g_list_length(lyrics));

    // 清理分割后的字符串数组
    g_strfreev(lines);

    lyric_log_debug("parse_lyrics: returning %d lyrics", g_list_length(lyrics));
    return lyrics;
}

/**
 * @brief 从文件中加载歌词
 * @param lyric_path 歌词文件路径
 * @return 包含所有歌词行的GList链表
 */
GList* load_lyrics(const gchar* lyric_path)
{
    gchar* lyric_txt = read_from_file(lyric_path);
    if (!lyric_txt) {
        return NULL;
    }
    
    GList* result = parse_lyrics(lyric_txt);
    g_free(lyric_txt);
    return result;
}

/**
 * @brief 释放 parse_lyrics 返回的歌词链表
 */
void free_lyrics_list(GList* lyrics) {
    if (!lyrics) {
        return;
    }
    for (GList* l = lyrics; l; l = l->next) {
        LyricLine* line = (LyricLine*)l->data;
        if (line) {
            g_free(line->text);
            g_slice_free(LyricLine, line);
        }
    }
    g_list_free(lyrics);
}